package server;
import java.util.*;

import msgs.*;

/**
 * Pops admin messages off the incoming queue, takes action on them as appropriate
 * Team 9: Andrew Hayworth, Brian Parrella, Ryan Kortmann, Nina Papa
 * @author Andrew Hayworth
 */

public class AdminParser extends Thread implements TTConstants {
	private AdminMsg amsg;
	private boolean go;
	
	public AdminParser() {
		go = true;
	}
	
	public void run() {
		while (go) {
			if(!(AdminListener.inQ.isEmpty())){
				// work , if we have something to do
				amsg = AdminListener.inQ.remove(0);
				switch(amsg.getAction()) {
				case LIST_BANNED_USERS:
					// returns the arraylist of those who have been banhammered....
					(new Thread() {
						public void run() {
							if (Arrays.equals(amsg.getAdminKey(), TTServer.adminTable.get(amsg.getName()).getClientKey())) {
								ArrayList<String> a = TTServer.banHammer;
								((AdminRequestMsg)amsg).setO(a);
							}
							else amsg.setResponse(Responses.DENY);
							AdminSender.outQ.add(amsg);
						}
					}).start();
					break;
				case LIST_USERS_ONLINE:
					// admin wants to know who's online
					(new Thread() {
						public void run() {
							if (Arrays.equals(amsg.getAdminKey(), TTServer.adminTable.get(amsg.getName()).getClientKey())) {
								ArrayList<String> a = new ArrayList<String>();
								a.addAll(TTServer.connTable.keySet());
								((AdminRequestMsg)amsg).setO(a);
								amsg.setResponse(Responses.OK);
							}
							else {
								amsg.setResponse(Responses.DENY);
							}
							AdminSender.outQ.add(amsg);
						}
					}).start();
					break;
				case LOGIN:
					(new NewAdminConnection(amsg)).start();
					break;
				case LOGOUT:
					(new Thread() {  
						public void run() {
							// pull them out of connection table
							if (Arrays.equals(amsg.getAdminKey(), TTServer.connTable.get(amsg.getName()).getClientKey())) {
								synchronized(TTServer.lock) {TTServer.adminTable.remove(amsg.getName());}
								amsg.setResponse(Responses.OK);
							}
							else amsg.setResponse(Responses.DENY);
							AdminSender.outQ.add(amsg);
						}
					}).start();
					break;
				case BANHAMMER:
					(new BanHammer(amsg)).start();
					break;
				case UNBANHAMMER:
					(new BanHammer(amsg)).start();
				 	break;
				case GETPROFILE:
					(new AdminProfileWorker(amsg)).start();
					break;
				case SETPROFILE:
					(new AdminProfileWorker(amsg)).start();
					break;
				case GETBL:
					(new AdminBLWorker(amsg)).start();
					break;
				case SETBL:
					(new AdminBLWorker(amsg)).start();
					break;
				case LOGCHAT:
					// implented , not sure if admintools will ever use it though
					(new Thread() {
						public void run() {
							if (Arrays.equals(amsg.getAdminKey(), TTServer.connTable.get(amsg.getName()).getClientKey())) {
								AdminLogMsg a = (AdminLogMsg) amsg;
								if (TTServer.chats.containsKey(a.getChatTitle())) {
									synchronized (TTServer.lock) {
										// this causes the chat thread to start writing to a file
										TTServer.chats.get(a.getChatTitle()).adminLog(a.isLogging());
									}
									amsg.setResponse(Responses.OK);
								}
								else {
									amsg.setResponse(Responses.DENY);
								}
								AdminSender.outQ.add(amsg);
								return;
							}
							else {
								amsg.setResponse(Responses.DENY);
								AdminSender.outQ.add(amsg);
							}
						}
					}).start();
					break;
				case LOGPM:
					// implemented on the server, client will NOT implement
					(new Thread() {
						public void run() {
							if (Arrays.equals(amsg.getAdminKey(), TTServer.connTable.get(amsg.getName()).getClientKey())) {
								// check first to see if they're both online ... then send messages to them!
								if (TTServer.connTable.containsKey(((AdminLogMsg)amsg).getU1()) && TTServer.connTable.containsKey(((AdminLogMsg)amsg).getU2())) {
									ClientSender.outQ.add(new ClientMsg(TTServer.connTable.get(((AdminLogMsg)amsg).getU1()), TTConstants.Actions.ADMIN_LOG_REQUEST, ((AdminLogMsg)amsg).getU1(), true));
									ClientSender.outQ.add(new ClientMsg(TTServer.connTable.get(((AdminLogMsg)amsg).getU2()), TTConstants.Actions.ADMIN_LOG_REQUEST, ((AdminLogMsg)amsg).getU2(), true));
									amsg.setResponse(Responses.OK);
									AdminSender.outQ.add(amsg);
								}
								else {
									amsg.setResponse(Responses.DENY);
									AdminSender.outQ.add(amsg);
								}
							}
							else {
								amsg.setResponse(Responses.DENY);
								AdminSender.outQ.add(amsg);
							}
						}
					}).start();
					break;
				case DISCONNECT_USER:
					// implemented 
					// forcibly disconnects a user
					// ie, the client system.exit(0) 's  
					(new Thread() {
						public void run() {
							if (Arrays.equals(amsg.getAdminKey(), TTServer.adminTable.get(amsg.getName()).getClientKey())) {
								if (TTServer.connTable.containsKey(((AdminRequestMsg)amsg).getUser())) {
									ClientSender.outQ.add(new ClientMsg(TTServer.connTable.get(((AdminRequestMsg)amsg).getUser()), Actions.ADMIN_DISCONNECT));
									TTServer.connTable.remove(((AdminRequestMsg)amsg).getUser());
									amsg.setResponse(Responses.OK);
								}
								else {
									amsg.setResponse(Responses.DENY);
								}
								AdminSender.outQ.add(amsg);
							}
							else {
								amsg.setResponse(Responses.DENY);
								AdminSender.outQ.add(amsg);
							}
						}
					}).start();
					break;
				case LIST_USER_CHATS:
					//returns a list of the running pms that a user has
					(new Thread() {
						public void run() {
							if (Arrays.equals(amsg.getAdminKey(), TTServer.adminTable.get(amsg.getName()).getClientKey())) {
								if (TTServer.connTable.containsKey(((AdminRequestMsg)amsg).getUser())) {
									ClientMsg c = new ClientMsg(TTServer.connTable.get(((AdminRequestMsg)amsg).getUser()), Actions.ADMIN_LIST_CHATS);
									c.setUser(amsg.getName());
									ClientSender.outQ.add(c);
									amsg.setResponse(Responses.OK);
									//AdminSender.outQ.add(amsg);
								}
								else {
									amsg.setResponse(Responses.DENY);
									AdminSender.outQ.add(amsg);
								}
								
							}
							else {
								amsg.setResponse(Responses.DENY);
								AdminSender.outQ.add(amsg);
							}
						}
					}).start();
					break;
				}
			}
			else {
				// nothing to do, sleep for a moment to not overload cpu
				try { Thread.sleep(100); }
				catch (InterruptedException e) { e.printStackTrace(); }
			}
		}
	}
}
